home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / TEX-UTIL / DVIPS_55 / dvips / src / c / scanpage < prev    next >
Text File  |  1994-05-07  |  10KB  |  298 lines

  1. /*
  2.  *   This routine scans a page for font definitions and character usage.
  3.  *   It keeps an estimate of the memory remaining in the printer, and
  4.  *   returns false when that memory is exhausted, unless scanning the
  5.  *   first page. Otherwise it returns 1 if no problems were found,
  6.  *   or 2 if it thinks the first page of a section may overflow memory.
  7.  */
  8. #include "dvips.h" /* The copyright notice in that file is included too! */
  9.  
  10. /*
  11.  *   These are the external routines we need.
  12.  */
  13.  
  14. extern shalfword dvibyte() ;
  15. extern halfword twobytes() ;
  16. extern integer threebytes() ;
  17. extern integer signedquad() ;
  18. extern shalfword signedbyte() ;
  19. extern shalfword signedpair() ;
  20. extern integer signedtrio() ;
  21. extern void skipover() ;
  22. extern void fontdef() ;
  23. extern void predospecial() ;
  24. extern int residentfont() ;
  25. extern Boolean virtualfont() ;
  26. extern void loadfont() ;
  27. extern void error() ;
  28. extern long getlong() ;
  29. extern void repack() ;
  30. extern void bopcolor() ;  /* IBM: color */
  31. extern integer firstboploc ;
  32. /*
  33.  *   And, of course, the globals it uses.
  34.  */
  35. #ifdef DEBUG
  36. extern integer debug_flag;
  37. #endif  /* DEBUG */
  38. extern fontdesctype *curfnt ;
  39. extern fontdesctype *baseFonts[] ;
  40. extern fontmaptype *ffont ;
  41. extern quarterword *curpos, *curlim ;
  42. extern integer fontmem ;
  43. extern integer pagecount ;
  44. extern integer pagenum ;
  45. extern Boolean compressed ;
  46. extern FILE *dvifile ;
  47. extern char errbuf[] ;
  48. extern frametype frames[] ;
  49. extern integer pagecost ;
  50. /*
  51.  * Charge pagecost for the cost of showing the character that *cd refers to
  52.  * and charge fontmem for the cost of downloading the character if necessary.
  53.  * A zero result indicates that we have run out of memory.
  54.  *   If the character is small (a small packet), we save 43 bytes (since we
  55.  *   use a single string instead of an array with integers in the PostScript.)
  56.  */
  57. Boolean
  58. prescanchar(cd)
  59. chardesctype *cd ;
  60. {
  61.    register quarterword *cras ;
  62.    register integer thischar ;
  63.  
  64.    if ((cd->flags & (PREVPAGE | THISPAGE)) == 0) {
  65.       /* the character hasn't been used before in the current section */
  66.       cras = cd->packptr ;
  67.       if (curfnt->resfont) {
  68.          thischar = PSCHARCOST ;
  69.          cd->flags |= THISPAGE ;
  70.       } else if (cras != NULL) {
  71.          thischar = CHARCOST ;
  72.          if (cd->flags & BIGCHAR)
  73.             thischar += 43 ;
  74.          if (compressed) {
  75.             if ((cd->flags & REPACKED) == 0) {
  76.                repack(cd) ;
  77.                cras = cd->packptr ;
  78.             }
  79.             if ((*cras & 4))
  80.                if ((*cras & 7) == 7)
  81.                   thischar += getlong(cras + 17) ;
  82.                else
  83.                   thischar += getlong(cras + 9) ;
  84.             else
  85.                thischar += getlong(cras + 5) ;
  86.          } else {
  87.             if ((*cras & 4))
  88.                if ((*cras & 7) == 7)
  89.                   thischar += getlong(cras + 1)
  90.                                           * ((getlong(cras + 5) + 7) >> 3) ;
  91.                else
  92.                   thischar += (cras[3] * 256L + cras[4]) *
  93.                                  ((cras[1] * 256L + cras[2] + 7) >> 3) ;
  94.             else
  95.                thischar += ((long)(cras[2] * ((cras[1] + 7) >> 3))) ;
  96.          }
  97.          cd->flags |= THISPAGE ;
  98.       } else
  99.          thischar = 0 ;
  100.       fontmem -= thischar ;
  101.       if (fontmem <= pagecost) {
  102.          if (pagecount > 0)
  103.             return(0) ;
  104.       }
  105.    }
  106.    return(1) ;
  107. }
  108. /*
  109.  * When a font is selected during the prescan, this routine makes sure that
  110.  * the tfm or pk file is loaded and charges fontmem for the VM overhead in
  111.  * creating the font.  The result is true unless the section must be aborted
  112.  * in order to keep this font from overflowing VM.
  113.  */
  114. Boolean
  115. preselectfont(f)
  116. fontdesctype *f ;
  117. {
  118.    curfnt = f ;
  119.    if (curfnt->loaded == 0 || curfnt->loaded == 3) {
  120.       if (!residentfont(curfnt))
  121.          if (!virtualfont(curfnt))
  122.             loadfont(curfnt) ;
  123.    }
  124.    if (curfnt->psname == 0) {
  125.       if (curfnt->loaded < 2) /* virtual font costs nothing (yet) */
  126.          if (curfnt->resfont)
  127.             fontmem -= PSFONTCOST ;
  128.          else {
  129.             fontmem -= FONTCOST + curfnt->maxchars ;
  130.             if (curfnt->loadeddpi != curfnt->dpi)
  131.                fontmem -= 48 ; /* for the new font matrix */
  132.          }
  133.       curfnt->psname = 1 ;
  134.       if (fontmem <= pagecost) {
  135.          if (pagecount > 0)
  136.             return(0) ;
  137.       }
  138.    }
  139.    return(1) ;
  140. }
  141. /*
  142.  *   Now our scanpage routine.
  143.  */
  144. short
  145. scanpage()
  146. {
  147.    register shalfword cmd ;
  148.    register chardesctype *cd ;
  149.    register fontmaptype *cfnt = 0 ;
  150.    integer fnt ;
  151.    register frametype *frp = frames ;
  152.  
  153.   if (firstboploc == 0)
  154.      firstboploc = ftell(dvifile) ;
  155.    pagecost = 0 ;
  156. #ifdef DEBUG
  157.    if (dd(D_PAGE))
  158. #ifdef SHORTINT
  159.    (void)fprintf(stderr,"Scanning page %ld\n", pagenum) ;
  160. #else   /* ~SHORTINT */
  161.    (void)fprintf(stderr,"Scanning page %d\n", pagenum) ;
  162. #endif  /* ~SHORTINT */
  163. #endif  /* DEBUG */
  164.    curfnt = NULL ;
  165.    curpos = NULL ;
  166.  
  167.    bopcolor(0) ; /* IBM: color - put current colorstack to bopstackdepth */
  168.  
  169.    while (1) {
  170.       switch (cmd=dvibyte()) {
  171. case 129: case 130: case 131: case 134: case 135: case 136: case 139:
  172. case 247: case 248: case 249: case 250: case 251: case 252: case 253:
  173. case 254: case 255: /* unimplemented or illegal commands */
  174.          (void)sprintf(errbuf,
  175.             "! DVI file contains unexpected command (%d)",cmd) ;
  176.          error(errbuf) ;
  177. case 132: case 137: /* eight-byte commands setrule, putrule */
  178.          (void)dvibyte() ;
  179.          (void)dvibyte() ;
  180.          (void)dvibyte() ;
  181.          (void)dvibyte() ;
  182. case 146: case 151: case 156: case 160: case 165: case 170:
  183.    /* four-byte commands right4, w4, x4, down4, y4, z4 */
  184.          (void)dvibyte() ;
  185. case 145: case 150: case 155: case 159: case 164: case 169:
  186.    /* three-byte commands right3, w3, x3, down3, y3, z3 */
  187.          (void)dvibyte() ;
  188. case 144: case 149: case 154: case 158: case 163: case 168:
  189.    /* two-byte commands right2, w2, x2, down2, y2, z2 */
  190.          (void)dvibyte() ;
  191. case 143: case 148: case 153: case 157: case 162: case 167:
  192.    /* one-byte commands right1, w1, x1, down1, y1, z1 */
  193.          (void)dvibyte() ;
  194. case 147: case 152: case 161: case 166: /* w0, x0, y0, z0 */
  195. case 138: case 141: case 142: /* nop, push, pop */
  196.          break ;
  197. case 133: case 128: cmd = dvibyte() ; /* set1 commands drops through */
  198. default:    /* these are commands 0 (setchar0) thru 127 (setchar 127) */
  199. /*
  200.  *   We are going to approximate that each string of consecutive characters
  201.  *   requires (length of string) bytes of PostScript VM.
  202.  */
  203.          if (curfnt==NULL)
  204.             error("! Bad DVI file: no font selected") ;
  205.          if (curfnt->loaded == 2) { /* scanning a virtual font character */
  206.             frp->curp = curpos ;
  207.             frp->curl = curlim ;
  208.             frp->ff = ffont ;
  209.             frp->curf = curfnt ;
  210.             if (++frp == &frames[MAXFRAME] )
  211.                error("! virtual recursion stack overflow") ;
  212.             cd = curfnt->chardesc + cmd ;
  213.             if (cd->packptr == 0)
  214.  error("! a non-existent virtual character is being used; check vf/tfm files") ;
  215.             curpos = cd->packptr + 2 ;
  216.             curlim = curpos + (256*(long)(*cd->packptr)+(*(cd->packptr+1))) ;
  217.             ffont = curfnt->localfonts ;
  218.             if (ffont==NULL)
  219.                curfnt = NULL ;
  220.             else if (!preselectfont(ffont->desc))
  221.                goto outofmem ;
  222.          } else {
  223.             pagecost++ ;
  224.             if (!prescanchar(curfnt->chardesc + cmd))
  225.                goto outofmem ;
  226.          }
  227.          break ;        
  228. case 171: case 172: case 173: case 174: case 175: case 176: case 177:
  229. case 178: case 179: case 180: case 181: case 182: case 183: case 184:
  230. case 185: case 186: case 187: case 188: case 189: case 190: case 191:
  231. case 192: case 193: case 194: case 195: case 196: case 197: case 198:
  232. case 199: case 200: case 201: case 202: case 203: case 204: case 205:
  233. case 206: case 207: case 208: case 209: case 210: case 211: case 212:
  234. case 213: case 214: case 215: case 216: case 217: case 218: case 219:
  235. case 220: case 221: case 222: case 223: case 224: case 225: case 226:
  236. case 227: case 228: case 229: case 230: case 231: case 232: case 233:
  237. case 234: case 235: case 236: case 237: case 238: /* font selection commands */
  238.          if (cmd < 235) fnt = cmd - 171 ; /* fntnum0 thru fntnum63 */
  239.          else {
  240.             fnt = dvibyte() ; /* fnt1 */
  241.             while (cmd-- > 235)
  242.                fnt = (fnt << 8) + dvibyte() ;
  243.          }
  244.          if (curpos || fnt > 255) {
  245.             for (cfnt=ffont; cfnt; cfnt = cfnt->next)
  246.                if (cfnt->fontnum == fnt) goto fontfound ;
  247.          } else
  248.             if (0 != (curfnt = baseFonts[fnt]))
  249.                goto fontfound2 ;
  250.  printf("Font number %d not found\n", fnt) ;
  251.             error("! no font selected") ;
  252. fontfound: curfnt = cfnt->desc ;
  253. fontfound2: if (!preselectfont(curfnt))
  254.               goto outofmem ;
  255.             break ;
  256. case 239: predospecial((integer)dvibyte(), 1) ; break ; /* xxx1 */
  257. case 240: predospecial((integer)twobytes(), 1) ; break ; /* xxx2 */
  258. case 241: predospecial(threebytes(), 1) ; break ; /* xxx3 */
  259. case 242: predospecial(signedquad(), 1) ; break ; /* xxx4 */
  260. case 243: case 244: case 245: case 246: fontdef(cmd-242) ; break ; /* fntdef1 */
  261. case 140: /* eop or end of virtual char */
  262.          if (curpos) {
  263.             --frp ;
  264.             curfnt = frp->curf ;
  265.             ffont = frp->ff ;
  266.             curlim = frp->curl ;
  267.             curpos = frp->curp ;
  268.             break ;
  269.          }
  270.          goto endofpage ; /* eop */
  271.       }
  272.    }
  273. endofpage:
  274.    if (fontmem > pagecost)
  275.       return(1) ;
  276.    if (pagecount > 0) {
  277.       return(0) ;
  278.     }  /* IBM: color */
  279. #ifdef SHORTINT
  280.       (void)fprintf(stderr, "Page %ld may be too complex to print\n", pagenum) ;
  281. #else   /* ~SHORTINT */
  282.       (void)fprintf(stderr, "Page %d may be too complex to print\n", pagenum) ;
  283. #endif  /* ~SHORTINT */
  284. /*
  285.  *   This case should be rare indeed.  Even with only 200K of virtual memory,
  286.  *   at 11 bytes per char, you can have 18K characters on a page.
  287.  */
  288.    return(2) ;
  289. outofmem:
  290.    if (frp != frames) {
  291.       curpos = frames->curp ;
  292.       curlim = frames->curl ;
  293.       ffont = frames->ff ;
  294.       curfnt = frames->curf ;
  295.    }
  296.    return 0 ;
  297. }
  298.